package com.rent.common.utils;


import org.apache.commons.lang3.math.NumberUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * @Author zhang
 * @create 2021/5/12 8:56
 */
public class CommonUtil {

    // 赌博概率论  赢了赢80% 输了输50%
    public static void main(String[] args) {
        double win = 1.0; // 赢的赔率
        double lose = 1.0; // 输的赔率 或者 1.0直接输光
        double total = 10000.0; // 初始金额 本钱
        double gameSum = 1000.0; // 每把游戏金额
        double commission = 0.03; // 抽成3% 赢一把抽水3%
        int gameCount = 50; // 游戏次数 玩几把
        int winRestart = 2; // 赢几把然后 用固定本钱开始
        int totalP = 10; // 总人数
        int winP = 0; // 赢的人数
        int loseP = 0; // 输的人数
        // 固定的玩的本钱是1000块, 意思是如果输了就从初始本钱中拿一千块做本
        // 如果赢了就翻次数 上面设置的次数 比如上面设置2次 就是说第一把赢了 就得将近2000 第二把赢了就将近4000
        // 然后把赢的钱存入初始本金中 再用1000块做本钱重新玩 如果没钱了就结束 有钱就继续 直到游戏次数玩完
        System.out.println("每个人的总金额:" + total);
        System.out.println("几个人玩总人数:" + totalP);
        BigDecimal winM = BigDecimal.ZERO;
        BigDecimal loseM = BigDecimal.ZERO;
        for (int m = 1; m < totalP + 1; m++) {
            BigDecimal money = BigDecimal.valueOf(total);
            // 每次玩的钱
            BigDecimal everyFix = BigDecimal.valueOf(gameSum);
            // 当前本次游戏金额
            BigDecimal endMoney = everyFix;
            // 剩余的金额
            money = money.subtract(everyFix);
//            System.out.println("用本钱开始玩:" + endMoney);
//            System.out.println("剩余的钱:" + money);
            int count = 0;
            for (int i = 1; i < gameCount + 1; i++) {
                Random random = new Random();
                // 随机布尔值
                boolean sj = random.nextBoolean();
                if (sj) { // 如果赢了就 赢80%
                    // 赢的钱
                    BigDecimal w = endMoney.multiply(BigDecimal.valueOf(win));
                    // 抽成
                    BigDecimal ms = w.multiply(BigDecimal.valueOf(commission)).setScale(2, RoundingMode.HALF_UP);
                    w = w.subtract(ms);
                    // 赢的钱 + 本钱
                    endMoney = endMoney.add(w).setScale(2, RoundingMode.HALF_UP);
//                    System.out.println("第" + i + "次赢了:" + endMoney);
                    count++;
                    // 如果连赢3把就把钱存起来
                    if (count >= winRestart) {
                        // 把钱存起来 剩余的钱 + 赢的钱
                        money = money.add(endMoney);
//                        System.out.println("总共的钱:" + money);
                        // 再把总金额 给1000的本钱出来
                        money = money.subtract(everyFix);
                        endMoney = everyFix;
                        count = 0;
                    }
                } else { // 如果输了 就输50%
                    count = 0;
                    // 剩余的钱
                    BigDecimal e = endMoney.multiply(BigDecimal.valueOf(lose)).setScale(2, RoundingMode.HALF_UP);
                    endMoney = endMoney.subtract(e);
                    // 没钱了
                    if (money.compareTo(BigDecimal.ZERO) <= 0) {
                        endMoney = BigDecimal.ZERO;
                        money = BigDecimal.ZERO;
//                        System.out.println("第" + i + "次输完了没钱了" + endMoney);
                        break;
                    }
                    // 输了没钱拿本钱来赌
                    if (money.compareTo(everyFix) >= 0) {
                        // 如果本钱还大于固定本钱就拿
                        endMoney = everyFix.add(endMoney);
                    } else {
                        // 否则剩余多少赌多少
                        endMoney = money;
                    }
                    // 剩余的钱
                    money = money.subtract(endMoney);
//                    System.out.println("第" + i + "次输了拿本钱:" + endMoney);
//                    System.out.println("输了赔的钱:" + e);
                }
//                BigDecimal left = endMoney.add(money);
//                System.out.println("本钱:" + endMoney);
//                System.out.println("剩余的钱:" + money);
            }
            BigDecimal end = money.add(endMoney);
            // 经过100次之后可以得出的结果
            System.out.println("第" + m + "个人最后赌博结果:" + end);
            if (end.compareTo(BigDecimal.valueOf(total)) > 0) {
                winM = winM.add(end).subtract(BigDecimal.valueOf(total));
                winP += 1;
            } else {
                loseM = BigDecimal.valueOf(total).subtract(end).add(loseM);
                loseP += 1;
            }
        }
        System.out.println("赢的人数:" + winP + "输的人数:" + loseP);
        System.out.println("总赢的钱:" + winM + "总输的钱:" + loseM);
    }

    /**
     * 分隔字符串数组 返回int 数组
     */
    public static List<Integer> getIntegerListBySplitString(String content, String reg) {
        content = StringUtils.trim(content);
        if (StringUtils.isEmpty(content)) return null;
        if (StringUtils.isEmpty(reg)) {
            reg = ",";
        }
        List<Integer> ids = new ArrayList<>();
        try {
            if (content.length() == 1 && NumberUtils.isCreatable(content)) {
                ids.add(Integer.valueOf(content));
                return ids;
            }
            if (content.contains(reg)) {
                String[] contents = content.split(reg);
                if (contents.length == 0) return null;
                for (String id : contents) {
                    ids.add(Integer.valueOf(id));
                }
            } else {
                if (NumberUtils.isCreatable(content)) {
                    ids.add(Integer.valueOf(content));
                    return ids;
                }
            }
        } catch (Exception e) {
            return null;
        }
        return ids;
    }


    /**
     * 分隔字符串数组 返回int 数组
     */
    public static List<String> getStringListBySplitString(String str, String reg) {
        str = StringUtils.trim(str);
        if (StringUtils.isEmpty(str)) return null;
        if (StringUtils.isEmpty(reg)) {
            reg = ",";
        }
        List<String> ids = new ArrayList<>();
        try {
            if (str.length() == 1 || !str.equalsIgnoreCase(reg)) {
                ids.add(str);
                return ids;
            }
            if (str.contains(reg)) {
                String[] contents = str.split(reg);
                if (contents.length == 0) return null;
                ids.addAll(Arrays.asList(contents));
            } else {
                ids.add(str);
            }
        } catch (Exception e) {
            return null;
        }
        return ids;
    }

    // 获取长度
    public static String getStringByLength(String string, int length) {
        if (string == null || string.isEmpty()) {
            StringBuilder str = new StringBuilder();
            for (int i = 0; i < length; i++) {
                str.append("0");
            }
            return str.toString();
        }
        if (string.length() == length) return string;
        if (string.length() < length) {
            StringBuilder str = new StringBuilder(string);
            for (int i = str.length(); i < length; i++) {
                str.insert(0, "0");
            }
            return str.toString();
        } else {
            return string.substring(string.length() - length);
        }
    }

    /**
     * 获取ip
     *
     * @param request 请求体
     * @return 结果
     */
    public static String getIPAddress(HttpServletRequest request) {
        String ip = null;
        //X-Forwarded-For：Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");
        if (ipAddresses == null || ipAddresses.isEmpty() || "unknown".equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP：apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.isEmpty() || "unknown".equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP：weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.isEmpty() || "unknown".equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP：有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ipAddresses == null || ipAddresses.isEmpty() || "unknown".equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP：nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }
        //有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
        if (ipAddresses != null && !ipAddresses.isEmpty()) {
            ip = ipAddresses.split(",")[0];
        }
        //还是不能获取到，最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

    /**
     * 判断系统类型
     *
     * @return 是否linux系统
     */
    public static boolean isLinuxSystem() {
        String os = System.getProperty("os.name").toLowerCase();
        return os.startsWith("linux");
    }

    /**
     * 判断系统类型
     *
     * @return 是否windows系统
     */
    public static boolean isWindowsSystem() {
        String os = System.getProperty("os.name").toLowerCase();
        return os.startsWith("win");
    }

    /**
     * 比较两个List集合是否相等
     * <p>注：1. 如果一个List的引用为<code>null</code>，或者其包含的元素个数为0，那么该List在本逻辑处理中都算作空；
     * <p>2. 泛型参数E涉及到对象，所以需要确保正确实现了对应对象的<code>equal()</code>方法。
     *
     * @param list1 列表1
     * @param list2 列表2
     * @return 是否相等
     */
    public static <E> boolean isListEqual(List<E> list1, List<E> list2) {
        // 两个list引用相同（包括两者都为空指针的情况）
        if (list1 == null && list2 == null) return true;
        if (list1 == list2) return true;
        if (list1 == null || list2 == null) return false;
        // 两个list都为空（包括空指针、元素个数为0）
        if (list1.isEmpty() && list2.isEmpty()) {
            return true;
        }
        // 两个list元素个数不相同
        if (list1.size() != list2.size()) {
            return false;
        }
        // 两个list元素个数已经相同，再比较两者内容
        // 采用这种可以忽略list中的元素的顺序
        // 涉及到对象的比较是否相同时，确保实现了equals()方法
        return new HashSet<>(list1).containsAll(list2);
    }

}
